/**
 * Copyright (c) 2020-2030 LiuBoTao [1211265557@qq.com]
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.amos.server.modules.upms.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.RequiredArgsConstructor;
import org.amos.core.basic.annotation.Log;
import org.amos.core.basic.constant.SystemConstant;
import org.amos.core.basic.utils.AmosUtils;
import org.amos.core.basic.utils.TreeUtils;
import org.amos.core.basic.utils.crud.WrapperBuilder;
import org.amos.server.modules.upms.dto.DeptDTO;
import org.amos.server.modules.upms.entity.Dept;
import org.amos.server.modules.upms.mapper.DeptMapper;
import org.amos.server.modules.upms.service.IDeptService;
import org.amos.server.modules.upms.vo.DeptTreeVO;
import org.amos.server.utils.SysTreeUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

/**
 * 部门 服务实现类
 *
 * @author CodeGenerator
 * @since 2020-12-20
 */
@Service
@RequiredArgsConstructor
public class DeptServiceImpl extends ServiceImpl<DeptMapper, Dept> implements IDeptService {

    private final SysTreeUtils<Dept> sysTreeUtils;

    @Override
    public Dept findById(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    @Log(value = "[更新部门信息]")
    public Boolean saveOrUpdateDept(Dept entity) {
        return this.saveOrUpdate(entity);
    }

    @Override
    @Log(value = "[删除部门信息]")
    public Boolean remove(Set<Long> ids) {
        List<Long> deptIds = new ArrayList<>();
        // 组装子集id
        ids.forEach(x -> {
            List<Long> childrenDictIds = sysTreeUtils.getChildrenIds(x, new ArrayList<>(), DeptMapper.class);
            deptIds.addAll(childrenDictIds);
        });
        // 合并
        deptIds.addAll(ids);
        UpdateWrapper<Dept> uw = new UpdateWrapper<>();
        uw.in(AmosUtils.toDbField(Dept::getId), deptIds).set(AmosUtils.toDbField(Dept::getIsDeleted), SystemConstant.SYS_DELETE_FLAG_ALREADY);
        return super.update(uw);
    }

    @Override
    public Dept getDeptInfo(Long id) {
        return baseMapper.selectById(id);
    }

    @Override
    public List<Long> getChildrenByParenId(Long id) {
        QueryWrapper<Dept> qw = new QueryWrapper<>();
        qw.eq(AmosUtils.toDbField(Dept::getParentId), id);
        qw.select(AmosUtils.toDbField(Dept::getId));

        List<Dept> depts = baseMapper.selectList(qw);
        List<Long> childrens = getChildrens(depts);
        childrens.add(id);
        return childrens;
    }

    @Override
    public List<Long> getChildrens(List<Dept> depts) {
        List<Long> results = new ArrayList<>();
        depts.forEach(dept -> {
            QueryWrapper<Dept> qw = new QueryWrapper<>();
            qw.eq(AmosUtils.toDbField(Dept::getParentId), dept.getId());
            qw.select(AmosUtils.toDbField(Dept::getId));
            List<Dept> list = baseMapper.selectList(qw);
            if (!ObjectUtils.isEmpty(list)) {
                results.addAll(getChildrens(list));
            }
            results.add(dept.getId());
        });
        return results;
    }

    @Override
    public List<DeptTreeVO> selectTree(DeptDTO dto) {
        List<Dept> depts = baseMapper.selectList(new WrapperBuilder().build(dto));
        if (CollUtil.isEmpty(depts)) {
            return new ArrayList<>();
        }
        List<DeptTreeVO> originalList = AmosUtils.listCopy(depts, DeptTreeVO.class);
        return TreeUtils.generateTrees(originalList);
    }

}
